﻿using GFluentCode.Tools;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;

namespace GFluentCode.CodeMaker.Template
{
    public class WebApiTemplate
    {
        public static string ToApiTemplate(Type type, string namespaceStr, string apiBaseNS, string entityNS, string apiBase)
        {
            var sb = new StringBuilder();

            sb.AppendLine($"using System;")
              .AppendLine($"using GFluentCode.Entity;")
              .AppendLine($"using GFluentCode.Tools;")
              .AppendLine($"using {apiBaseNS};")
              .AppendLine($"using {entityNS};")
              .AppendLine($"using {type.Namespace};")
              .AppendLine()
              .AppendLine($"namespace {namespaceStr}")
              .AppendLine($"{{")
              .AppendLine($"    public class {type.Name.Replace("ORM", "Controller")}:{(apiBase.GIsEmpty(true) ? "ApiController" : apiBase)}")
              .AppendLine($"    {{");

            var ormName = type.Name;
            //方法
            var mds = type.GetMethods();
            foreach (var md in mds)
            {
                //自动生成的跳过
                if (md.Attributes == (MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName)) continue;

                if (md.Attributes == MethodAttributes.Private) continue;

                var mdName = md.Name;
                //参数
                var ps = md.GetParameters();
                //返回类型
                var rType = md.ReturnType.Name;

                var rName = ReturnTypeChange(rType, md.ReturnType);
                if (ps.Length <= 0)
                {
                    sb.AppendLine($"        public {rName} {mdName} ()")
                      .AppendLine($"        {{")
                      .AppendLine($"            var orm = new {ormName}();")
                      .AppendLine($"            {(rName.Equals("void") ? "" : "return ")}orm.{mdName}();")
                      .AppendLine($"        }}")
                      .AppendLine();
                    continue;
                }

                sb.Append($"        public {rName} {mdName} (");
                var psStr = string.Empty;
                var param = string.Empty;
                for (var i = 0; i < ps.Length; i++)
                {
                    //参数类型
                    var pType = ps[i].ParameterType.Name;
                    var pName = ps[i].Name;

                    psStr += $"{ReturnTypeChange(pType, md.ReturnType)} {pName}";
                    param += $"{pName}";
                    if (i + 1 < ps.Length)
                    {
                        psStr += ",";
                        param += ",";
                        continue;
                    }
                    sb.Append($"{psStr})");

                    sb.AppendLine()
                      .AppendLine($"        {{")
                      .AppendLine($"            var orm = new {ormName}();")
                      .AppendLine($"            {(rName.Equals("void") ? "" : "return ")}orm.{mdName}({param});")
                      .AppendLine($"        }}")
                      .AppendLine();
                }

            }
            sb.AppendLine($"    }}")
              .AppendLine($"}}");

            return sb.ToString();
        }

        static string ReturnTypeChange(string typeName, Type returnType)
        {
            var tName = typeName.ToLower();
            if (tName.Equals("boolean") || tName.Equals("bool")) return "bool";
            else if (tName.Equals("string")) return "string";
            else if (tName.Equals("int32")) return "int";
            else if (tName.Contains("ilist"))            
                return $"IList<{returnType.GetGenericArguments()[0].Name}>";
            else if(tName.Contains("Expression".ToLower()))
            {
                return $"Expression<Function<>>";
            }
            
            else return typeName;
        }
    }
}
